package br.com.felix.fwt.ui;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;

import br.com.felix.fwt.log.LoggerFactory;
import br.com.felix.fwt.ui.exception.ComponentRenderException;
import br.com.felix.fwt.util.Util;


/**
 * The Class SelectObjectBox implements an HTML select component. It is like the
 * ComboBox component, except that this component uses domain objects under its
 * hood.
 */
public class SelectObjectBox<T> extends BaseComponent {
	
	private static final long serialVersionUID = 7518700585781614726L;
	
	private static Logger logger = LoggerFactory.getLogger(SelectObjectBox.class);
	
	private List<T> lstObjects;
	
	


	/**
	 * Instantiates a new combo box.
	 */
	public SelectObjectBox() {
		this.cssClass = "fwtselectobjectbox";
	}
	


	/**
	 * Instantiates a new SelectObjectBox and adds all the objects of the specified collection.
	 * */
	public SelectObjectBox(Collection<T> col) {
		this();
		addAll(col);
	}



	/**
	 * This method is not supported by this object.
	 */
	@Override
	public void add(BaseComponent ... child) {
		throw new UnsupportedOperationException("This method is not supported by this object. Use addObject(T) instead.");
	}
	


	/**
	 * Adds all the objects in the list to the combo box.
	 */
	public void addAll(Collection<T> lstOption) {
		if (lstObjects == null) {
			lstObjects = new ArrayList<T>();
		}
		for (T t : lstOption) {
			lstObjects.add(t);
		}
	}
	


	/**
	 * Adds the object in the combo box.
	 */
	public void addObject(T ...objects) {
		if (lstObjects == null) {
			lstObjects = new ArrayList<T>();
		}
		for (T obj : objects) {
			lstObjects.add(obj);
		}
	}
	


	/**
	 * Gets the object selected by the user.
	 */
	public T getSelectedObject() {
	    String value = getValue();
		if (!Util.isNullOrEmpty(value)) {
			return lstObjects.get(Integer.parseInt(value));
		}
		return null;
	}
	


	/*
	 * (non-Javadoc)
	 * 
	 * @see br.com.felix.fwt.ui.BaseComponent#write(java.io.PrintWriter)
	 */
	@Override
	public void write(PrintWriter out) throws ComponentRenderException {
		if(!authorized()) return;
		PresentationMode pMode = getPresentationMode();
		switch (pMode) {
			case EDIT:
				out.write("\n<select name=\"");
				out.write(getName());

				out.write("\" class=\"");
				out.write(cssClass);
				out.write("\" ");
				if (style != null) {
					out.write(style);
				}
				out.write(">");
				if (lstObjects != null) {
					String myValue = getValue();
					T object;
					String key;
					for (int i=0; i<lstObjects.size(); i++) {
						key = String.valueOf(i);
						object = lstObjects.get(i);
						out.write("\n<option value=\"");
						out.write(key);
						out.write("\" ");
						if (key.equals(myValue)) {
							out.write(" selected ");
						}
						out.write(">");
						out.write(object.toString());
						out.write("</option>");
					}
				}
				out.write("\n</select>");
				break;
			case SHOW:
				if (lstObjects != null) {
				    String myValue = getValue();
					if (!Util.isNullOrEmpty(myValue)) {
						Integer key = Integer.parseInt(myValue);
						T object = lstObjects.get(key);
						out.write(object.toString());
					}
				}
				break;
			case DELETED:
				if (lstObjects != null) {
				    String myValue = getValue();
					if (!Util.isNullOrEmpty(myValue)) {
						Integer key = Integer.parseInt(myValue);
						T object = lstObjects.get(key);
						out.write("\n<del>");
						out.write(object.toString());
						out.write("\n</del>");
					}
				}
				break;
		}
	}



	public void setSelectedObject(T newValue) {
		for (int i=0; i<lstObjects.size();i++){
			if (lstObjects.get(i).equals(newValue)){
				super.setValue(String.valueOf(i));
			}
		}
	}



    @Override
    public boolean isInputControl() {
        return true;
    }
}
